﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SharedLib.WinFormMVCFramework;
using TracyGUI.View;
using Microsoft.Practices.Unity;
using Tracy.DataModel;
using TracyGUI.View.EntryTabs;
using TracyGUI.View.UIComponent;
using TracyGUI.Model;
using System.Xml;
namespace TracyGUI.Controller.EntryTabs
{
    class EntryTabsViewController : ControllerBase<IEntryTabsView>, IController<IEntryTabsView>, IHasViewState
    {
        
        protected override IEntryTabsView ResolveView()
        {
            return Tracy.TracyFacade.Instance.DIContainer.Resolve<IEntryTabsView>();
        }

        private List<ITabPageViewController> _tabPageViewControllers = new List<ITabPageViewController>();
        public EntryTabsViewController()
        {
            View.EntryTabControl.PageRemoved += new EventHandler<TabPageEvent>(EntryTabControl_PageRemoved);
            View.EntryTabControl.PageMoved += new EventHandler<SharedLib.EnhancedEventArgs>(EntryTabControl_PageMoved);
        }

        void EntryTabControl_PageMoved(object sender, SharedLib.EnhancedEventArgs e)
        {
            Tracy.TracyFacade.Instance.ExceptionManager.Process(() =>
            {
                int dragIndex = (int)e.Attributes["dragIndex"];
                int dropIndex = (int)e.Attributes["dropIndex"];
                ITabPageViewController tab = _tabPageViewControllers[dragIndex];
                _tabPageViewControllers.RemoveAt(dragIndex);
                _tabPageViewControllers.Insert(dropIndex, tab);
            }, "UI Policy");
        }

        void EntryTabControl_PageRemoved(object sender, TabPageEvent e)
        {
            Tracy.TracyFacade.Instance.ExceptionManager.Process(() =>
            {
                foreach (ITabPageViewController tab in _tabPageViewControllers)
                {
                    if (tab.View.TabPage == e.TabPage)
                    {
                        _tabPageViewControllers.Remove(tab);
                        return;
                    }
                }
            }, "UI Policy");
        }

        public void AddTabPage(ITabPageViewController tabPageViewController)
        {
            _tabPageViewControllers.Add(tabPageViewController);
            View.EntryTabControl.TabPages.Add(tabPageViewController.View.TabPage);
            SwitchToTab(tabPageViewController);
        }

        public void ReplaceTabPage(ITabPageViewController oldTab, ITabPageViewController newTab)
        {
            int index = _tabPageViewControllers.IndexOf(oldTab);
            _tabPageViewControllers.RemoveAt(index);
            _tabPageViewControllers.Insert(index, newTab);

            index = View.EntryTabControl.TabPages.IndexOf(oldTab.View.TabPage);
            View.EntryTabControl.TabPages.RemoveAt(index);
            View.EntryTabControl.TabPages.Insert(index, newTab.View.TabPage);
            SwitchToTab(newTab);
            if (oldTab is IDisposable)
            {
                ((IDisposable)oldTab).Dispose();
            }
        }

        private void SwitchToTab(ITabPageViewController tabPageViewController)
        {
            View.EntryTabControl.SelectTab(tabPageViewController.View.TabPage);
        }

        public void SwitchToEntryTab(Entry entry, bool openInNewTab = false)
        {
            if (openInNewTab)
            {
                AddTabPage(new SingleEntryTabPageViewController(entry));
            }
            else
            {
                ITabPageViewController oldTab = null;
                foreach (ITabPageViewController tab in _tabPageViewControllers)
                {
                    if (tab is SingleEntryTabPageViewController)
                    {
                        if (oldTab == null) oldTab = tab;
                        if (((SingleEntryTabPageViewController)tab).Data.ID == entry.ID)
                        {
                            SwitchToTab(tab);
                            return;
                        }
                    }
                }

                //If not found
                if (oldTab == null)
                {
                    AddTabPage(new SingleEntryTabPageViewController(entry));
                }
                else
                {
                    ReplaceTabPage(oldTab, new SingleEntryTabPageViewController(entry));
                }
            }
        }

        public void SwitchToAllEntriesTab()
        {
            foreach (ITabPageViewController tab in _tabPageViewControllers)
            {
                if (tab is AllEntriesTabPageViewController)
                {
                    SwitchToTab(tab);
                    return;
                }
            }

            //If not found
            AddTabPage(new AllEntriesTabPageViewController());
        }

        public void SwitchToSearchTab(string keyword)
        {
            foreach (ITabPageViewController tab in _tabPageViewControllers)
            {
                if (tab is SearchResultTabPageViewController)
                {
                    ((SearchResultTabPageViewController)tab).Keyword = keyword;
                    SwitchToTab(tab);
                    return;
                }
            }

            //If not found
            AddTabPage(new SearchResultTabPageViewController(keyword));
        }

        #region IHasViewState Members

        public void LoadViewState(ViewStateManager manager, XmlElement viewStateNode)
        {
            ITabPageViewController selectedController = null;
            foreach (XmlElement subViewStateNode in viewStateNode.SelectNodes("view-state"))
            {
                ITabPageViewController currentTab = null;
                string selected = subViewStateNode.GetAttribute("selected");
                string controllerName = subViewStateNode.GetAttribute("controller");
                if (controllerName == typeof(AllEntriesTabPageViewController).Name)
                {
                    currentTab = new AllEntriesTabPageViewController();
                }
                else if (controllerName == typeof(SearchResultTabPageViewController).Name)
                {
                    currentTab = new SearchResultTabPageViewController();
                }
                else if (controllerName == typeof(SingleEntryTabPageViewController).Name)
                {
                    string entryID = subViewStateNode.GetAttribute("entry-id");
                    if (Tracy.TracyFacade.Instance.EntryProvider.IsItemExisting(entryID))
                    {
                        currentTab = new SingleEntryTabPageViewController();
                    }
                }
                if (currentTab != null)
                {
                    currentTab.LoadViewState(manager, subViewStateNode);
                    if (selected == "true") selectedController = currentTab;
                    AddTabPage(currentTab);
                }
            }
            if (selectedController != null) View.EntryTabControl.SelectTab(selectedController.View.TabPage);
        }

        public void SaveViewState(ViewStateManager manager, XmlElement viewStateNode, XmlDocument doc)
        {
            foreach (ITabPageViewController tab in _tabPageViewControllers)
            {
                XmlElement generatedNode = manager.SaveViewState(tab, viewStateNode);
                if (tab.View.TabPage == View.EntryTabControl.SelectedTab) generatedNode.SetAttribute("selected", "true");
            }
        }

        #endregion
    }
}
